from typing import AsyncGenerator
import asyncpg
import redis.asyncio as redis
from src.core.config import settings
from src.repositories.user import UserRepository
from src.services.auth import AuthService

# Global connection pools
db_pool: asyncpg.Pool = None
redis_client: redis.Redis = None


async def init_db_pool():
    """Initialize PostgreSQL connection pool."""
    global db_pool
    db_pool = await asyncpg.create_pool(
        settings.DATABASE_URL.replace("postgresql+asyncpg://", "postgresql://"),
        min_size=10,
        max_size=settings.DATABASE_POOL_SIZE,
        command_timeout=60
    )
    return db_pool


async def init_redis_client():
    """Initialize Redis client."""
    global redis_client
    redis_client = redis.from_url(
        settings.REDIS_URL,
        password=settings.REDIS_PASSWORD,
        encoding="utf-8",
        decode_responses=False
    )
    return redis_client


async def close_db_pool():
    """Close PostgreSQL connection pool."""
    global db_pool
    if db_pool:
        await db_pool.close()


async def close_redis_client():
    """Close Redis client."""
    global redis_client
    if redis_client:
        await redis_client.close()


async def get_db_pool() -> asyncpg.Pool:
    """Get database connection pool."""
    return db_pool


async def get_redis_client() -> redis.Redis:
    """Get Redis client."""
    return redis_client


async def get_user_repository() -> UserRepository:
    """Get user repository instance."""
    return UserRepository(db_pool)


async def get_auth_service() -> AuthService:
    """Get auth service instance."""
    user_repository = await get_user_repository()
    return AuthService(user_repository, redis_client)